// SendingThread.cpp : implementation file
//

#include "stdafx.h"
#include "FileSender.h"
#include "SendingThread.h"


// CSendingThread

IMPLEMENT_DYNCREATE(CSendingThread, CWinThread)

CSendingThread::CSendingThread()
: m_strDestFolder(_T(""))
, byBuffer(NULL)
, pFile(NULL)
, m_pRecvData(NULL)
, m_pProgressOne(NULL)
, m_pProgressAll(NULL)
, m_pTextOne(NULL)
, m_pTextAll(NULL)
{
}

CSendingThread::~CSendingThread()
{
}

BOOL CSendingThread::InitInstance()
{
	// TODO:  perform and per-thread initialization here
	AfxSocketInit();
	byBuffer = new BYTE[BUFFER_SIZE];

	return TRUE;
}

int CSendingThread::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	TRACE(_T("Exit instance\n"));
	delete byBuffer;
	pFile->Abort();
	delete pFile;
	pFile = NULL;
	PostMessage(m_hwnd, WM_USER + 2, NULL, NULL);

	return CWinThread::ExitInstance();
}

void CSendingThread::SetSettings(CConnSet &csSet)
{
	m_csSettings.IsServer(csSet.IsServer());
	m_csSettings.IpAddrDw(csSet.IpAddrDw());
	m_csSettings.UiPort(csSet.UiPort());
}

BEGIN_MESSAGE_MAP(CSendingThread, CWinThread)
END_MESSAGE_MAP()


// CSendingThread message handlers


int CSendingThread::Run()
{
	TRACE(_T("Thread run()\n"));
	// TODO: Add your specialized code here and/or call the base class
	CFileStatus fsStatus;
	CString strOne;
	CString strAll;
	DWORD dwBytesThisTime;
	DWORD dwAllBytes = 0;
	
	if(m_csSettings.IsServer())
	{
		m_sListener.Create(m_csSettings.UiPort() + 1);
		m_sListener.Listen();
		
		while(m_sListener.Accept(m_sConnection) == SOCKET_ERROR)
			Sleep(100);

		m_sListener.Close();
	}
	else
	{
		m_sConnection.Create();
		while(m_sConnection.Connect(m_csSettings.IpAddrStr(), m_csSettings.UiPort() + 1) == SOCKET_ERROR)
			Sleep(100);
	}

	if(m_Plik.GetState() == IDS_UPRDY)
	{
		pFile = new CFile;
		pFile->Open(m_Plik.GetPath(), CFile::modeRead);
		pFile->GetStatus(fsStatus);

		m_sConnection.Send(&fsStatus, sizeof(fsStatus));

		while(dwAllBytes < fsStatus.m_size)
		{
			dwBytesThisTime = pFile->Read(byBuffer, BUFFER_SIZE);
			m_sConnection.Send(byBuffer, dwBytesThisTime);
			dwAllBytes += dwBytesThisTime;

			ShowProgress(fsStatus, dwBytesThisTime, dwAllBytes);
		}
	}
	else
	{
		pFile = new CFile;
		pFile->Open(m_strDestFolder + m_Plik.GetName(), CFile::modeWrite | CFile::modeCreate | CFile::shareExclusive);

		m_sConnection.Receive(&fsStatus, sizeof(fsStatus));
		while(dwAllBytes < fsStatus.m_size)
		{
			dwBytesThisTime = m_sConnection.Receive(byBuffer, BUFFER_SIZE);
			dwAllBytes += dwBytesThisTime;
			pFile->Write(byBuffer, dwBytesThisTime);

			ShowProgress(fsStatus, dwBytesThisTime, dwAllBytes);
		}
	}

	m_sConnection.Close();

	PostQuitMessage(0);

	return CWinThread::Run();
}


void CSendingThread::ShowProgress(CFileStatus &fsStatus, DWORD &dwBytesThisTime, DWORD &dwAllBytes)
{
	CString strOne;
	CString strAll;
	int iPos = 0;
	float fDone;
	float fAll;

	strOne.LoadString(IDS_TEXTONE);
	strOne.Append(_T(" "));
	strOne.Append(m_Plik.GetName());
			
	fDone = (float)dwAllBytes / 1024;
	if(fDone / 1024 > 1800)
	{
		fDone /= 1024 * 1024;
		strOne.AppendFormat(_T("\t%.2f GB / "), fDone);
	}
	else if(fDone > 1800)
	{
		fDone /= 1024;
		strOne.AppendFormat(_T("\t%.2f MB / "), fDone);
	}
	else
	{
		strOne.AppendFormat(_T("\t%.2f KB / "), fDone);
	}
			
	fAll = (float)fsStatus.m_size / 1024;
	if(fAll / 1024 > 1800)
	{
		fAll /= 1024 * 1024;
		strOne.AppendFormat(_T("%.2f GB"), fAll);
	}
	else if(fAll > 1800)
	{
		fAll /= 1024;
		strOne.AppendFormat(_T("%.2f MB"), fAll);
	}
	else
	{
		strOne.AppendFormat(_T("%.2f KB"), fAll);
	}


	strAll.LoadString(IDS_TEXTALL);
	strAll.AppendFormat(_T(" %d / %d"), m_pRecvData->m_nAllRecvFiles, m_pRecvData->m_nAllFiles);
			
	fDone = (float)m_pRecvData->m_nAllRecvBytes / 1024;
	if(fDone / 1024 > 1800)
	{
		fDone /= 1024 * 1024;
		strAll.AppendFormat(_T("\t%.2f GB / "), fDone);
	}
	else if(fDone > 1800)
	{
		fDone /= 1024;
		strAll.AppendFormat(_T("\t%.2f MB / "), fDone);
	}
	else
	{
		strAll.AppendFormat(_T("\t%.2f KB / "), fDone);
	}
			
	fAll = (float)m_pRecvData->m_nAllBytes / 1024;
	if(fAll / 1024 > 1800)
	{
		fAll /= 1024 * 1024;
		strAll.AppendFormat(_T("%.2f GB"), fAll);
	}
	else if(fAll > 1800)
	{
		fAll /= 1024;
		strAll.AppendFormat(_T("%.2f MB"), fAll);
	}
	else
	{
		strAll.AppendFormat(_T("%.2f KB"), fAll);
	}
			
	m_pTextOne->SetWindowText(strOne);
	m_pTextAll->SetWindowText(strAll);

	iPos = (int)((float)dwAllBytes / (float)fsStatus.m_size * 100);
	m_pProgressOne->SetPos(iPos);
	m_pRecvData->m_nAllRecvBytes += dwBytesThisTime;
	iPos = (int)((float)m_pRecvData->m_nAllRecvBytes / (float)m_pRecvData->m_nAllBytes * 100);
	m_pProgressAll->SetPos(iPos);
}
